//#define __FORCE_TRACE__
//#define __FORCE_DEBUG__
//#define __FORCE_INFO__
#define THIS_FILE "ia\fn_defend.sqf"
#include <tmf_constants.h>
#include <tmf_macros.h>

TRACE_1("Start",_this);
TMFPROFILERSTART;

private ["_grp", "_pos","_debug","_units","_list","_wp","_staticWeapons","_bldgpos","_bldgs","_pos_details"];
DEFAULT_PARAM(_grp,0,grpNull);
DEFAULT_PARAM(_pos,1,[]);
DEFAULT_PARAM(_debug,2,false);

if (AND_ALSO((!isnull _grp),IS_OBJECT(_grp))) then {
	_grp = group _grp;
};
if (AND_ALSO((!isnull _grp),IS_GROUP(_grp))) then {
	if (!isServer && !(local (leader _grp))) exitWith { ERROR_1("Execution should be on server or local to the unit",_this); };
	if (IS_STRING(_pos) && {IS_MARKER(_pos)}) then {
		_pos = markerPos _pos;
	};
	if (!AND_ALSO(IS_ARRAY(_pos),(count _pos == 3))) then {
		_pos = getPos (leader _grp);
	};

	_grp setBehaviour "AWARE";

	_units = (units _grp);
	DEBUG_1("Beginning",ARR_3(_grp,_pos,_units));
	if ((count _pos != 3) || {(([0,0,0] vectorDistance _pos) < 1)} || {count _units <= 0}) exitWith {
		ERROR("Position not set or empty group");
	};

	[_grp] call FFUNC(deleteWaypoints);

	_wp = _grp addWaypoint [_pos, 10];
	_wp setWaypointType "HOLD";

	// We send units to staticWeapons if any.
	_list = nearestObjects [_pos, ["StaticWeapon"], 100];
	_staticWeapons = [];
	{if ((_x emptyPositions "gunner") > 0) then {_staticWeapons set [count _staticWeapons, _x]}} forEach _list;
	{
		if ((count _units) > 0) then {
			if ((random 1) > 0.1) then {
				private ["_unit"];
				_unit = (_units select ((count _units) - 1));
				_unit assignAsGunner _x;
				[_unit] orderGetIn true;
				TRACE_1("Assigned as gunner",ARR_3(_grp, _unit, typeof _x));
				[_unit, _x] spawn {
					sleep (15 + random (15));
					if (vehicle(_this select 0) == (_this select 0) && alive (_this select 1)) then {
						(_this select 0) setPos (getPos (_this select 1));
						(_this select 0) moveInGunner (_this select 1);
					};
				};
				_units resize ((count _units) - 1);
			};
		};
	} forEach _staticWeapons;

	// We send units (if any are left) to building pos if any
	_bldgpos = [];
	if (count _units > 0) then {
		// NEARESTTAG
		//_bldgs = nearestObjects [_pos, ["Building"], 60];
		_bldgs = _pos nearObjects ["Building", 60];
		If (count _bldgs > 0) then {
			{
				private["_i","_y"];
				// We only take the first position of each building.
				_bldarr = [];
				// Using homebrewn building pos
				_bldarr = [_x,[TMF_BUILDING_POS_COMBAT,TMF_BUILDING_POS_DOOR],True, True] call FFUNC(buildingPosArray);
				DEBUG_1("Building Array",ARR_3(_grp,count _units, _bldarr));
				If (count _bldarr > 0) then {
					_bldgpos = [_bldgpos, _bldarr] call FFUNC(arrayPushStack);
				};
				if (count _bldarr <= 0) then {
					_found = true;
					_count = 0;
					while {_found} do {
						_y = _x buildingPos _count;
						_found = (_y vectorDistance [0,0,0]) > 1;
						if (_found) then {
							_bldgpos set [count _bldgpos, [_y, random(360), if(random(10)>5) then {"UP"} else {"MIDDLE"}]];
						};
						_count = _count + 1;
					};
					_found = true;
					_count = 0;
					while {_found} do {
						_y = _x buildingExit _count;
						_found = (_y vectorDistance [0,0,0]) > 1;
						if (_found) then {
							_bldgpos set [count _bldgpos, [_y, random(360), "UP"]];
						};
						_count = _count + 1;
					};
				};
			} forEach _bldgs;
			
			_bldgpos = _bldgpos call FFUNC(arrayRandomize);
			DEBUG_1("BuildingPos to assign and units",ARR_3(_grp, count _bldgpos, (count _units)));
			{
				(random 1);
				if ((count _units) > 0) then {
					_pos_details = _x;
					DEBUG_1("Position details",_pos_details);
					if ((random 1) > 0.1 AND ((_pos_details select 0) vectorDistance [0,0,0]) > 0) then {
						private ["_unit"];
						_unit = (_units select ((count _units) - 1));
						doStop _unit;
						sleep 0.5;
						_unit MoveTo (_pos_details select 0);
						_units resize ((count _units) - 1);
						DEBUG_1("Position assigned",ARR_3(_grp, (_pos_details select 0), _unit));
					};
				};
			} forEach _bldgpos;
		};
	};
	DEBUG_1("Positions found for assignment",ARR_3(_grp, count(_staticWeapons), count(_bldgpos)));

	private ["_handle"];
	_handle = _units spawn {
		sleep 5;
		{
			if ((random 1) > 0.4) then {
				doStop _x;
				sleep 0.5;
				_x action ["SitDown", _x];	
			};	
		} forEach _this;
	};
	_grp setVariable ["defend",_pos];

	If (_debug) then {
		_grp spawn {
			private ["_group","_units","_marker","_marker_name"];
			sleep 5;
			_group = _this;
			_units = units _group;
			{
				_marker_name = Format["Unit%1",str(_x)];
				_marker = createMarker[_marker_name,[(getPos _x) select 0,(getPos _x) select 1]];
				_marker setMarkerShape "ICON";
				_marker_name setMarkerType "hd_dot";
				_marker_name setMarkerColor "ColorRed";
				_marker_name setMarkerText str(_x);
			} foreach _units;
			while {alive (leader _group)} do {
				sleep 5;
				{
					private ["_marker_name"];
					_marker_name = Format["Unit%1",str(_x)];
					_marker_name setMarkerPos [getPos _x select 0,getPos _x select 1];
				} forEach _units;
			};
		};
	};
} else {
	ERROR("Group is null");
};
TRACE("End");
TMFPROFILERSTOP;